package com.jiuli_travel.blog_service.controller;

import com.jiuli_travel.blog_service.model.dto.blog.BlogInsertRequest;
import com.jiuli_travel.blog_service.model.dto.blog.BlogQueryRequest;
import com.jiuli_travel.blog_service.model.dto.blog.HandleCountChangeRequest;
import com.jiuli_travel.blog_service.model.dto.blog.SearchBlogsRequest;
import com.jiuli_travel.blog_service.service.IBlogService;
import com.jiuli_travel.utils.Result;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping(value = "/blog")
public class BlogController {

    @Autowired
    private IBlogService blogService;

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    /**
     * 分页查询 blog 信息
     */
    @GetMapping("/selectBlogsByPage")
    @Parameters({
            @Parameter(name = "token",description = "请求token",required = true,in = ParameterIn.HEADER),
    })
    public Result selectBlogsByPage(BlogQueryRequest blogQueryRequest){
        return blogService.selectBlogsByPage(blogQueryRequest);
    }

    /**
     * 发布个人 blog （user）
     */
    @PostMapping("/publishBlog")
    @Parameters({
            @Parameter(name = "token",description = "请求token",required = true,in = ParameterIn.HEADER),
    })
    public void publishBlog(@RequestBody BlogInsertRequest blogInsertRequest){
        blogService.publishBlog(blogInsertRequest);
    }

    /**
     * del个人 blog （批量删除）
     */
    @DeleteMapping("/batchDelBlog")
    @Parameters({
            @Parameter(name = "token",description = "请求token",required = true,in = ParameterIn.HEADER),
    })
    public void batchDelBlog(List<Long> blogIds){
        blogService.batchDelBlog(blogIds);
    }

    /**
     * 自动`补`全功能 （操作es）
     */
    @GetMapping("/completionSuggest")
    @Parameters({
            @Parameter(name = "token",description = "请求token",required = true,in = ParameterIn.HEADER),
    })
    public Result completionSuggest(String searchText) throws IOException {
        // 1. 准备请求
        SearchRequest blogEsRequest = new SearchRequest("blog_es");

        // 2. DSL
        blogEsRequest.source()
                .query(QueryBuilders.matchQuery("title", searchText))
                .fetchSource(new String[]{""}, null)
                .highlighter(new HighlightBuilder().field("title").requireFieldMatch(false));

        // 3. 发起请求
        SearchResponse searchResponse = restHighLevelClient.search(blogEsRequest, RequestOptions.DEFAULT);

        // 4. 解析数据
        List<String> titleStrList = new ArrayList<>();
        SearchHit[] hits = searchResponse.getHits().getHits();
        for (SearchHit hit : hits) {
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField highlightField = highlightFields.get("title");
            if (highlightField != null) {
                String titleStr = highlightField.getFragments()[0].toString();
                titleStrList.add(titleStr);
            }
        }
        return Result.ok(titleStrList);
    }

    /**
     * 搜索blogs
     * @param searchBlogsRequest
     * @return
     * @throws IOException
     */
    @GetMapping("/searchBlogs")
    @Parameters({
            @Parameter(name = "token",description = "请求token",required = true,in = ParameterIn.HEADER),
    })
    public Result searchBlogs(SearchBlogsRequest searchBlogsRequest) throws IOException {
        String searchText = searchBlogsRequest.getSearchText();
        Integer from = searchBlogsRequest.getFrom();
        Integer size = searchBlogsRequest.getSize();
        return blogService.searchBlogs(searchText, from, size);
    }

    /**
     * 处理 liked | view | collect
     * @param handleCountChangeRequest 门面模式处理
     */
    @PutMapping("/handelCountChange")
    @Parameters({
            @Parameter(name = "token",description = "请求token",required = true,in = ParameterIn.HEADER),
    })
    public void handelCountChange(@RequestBody HandleCountChangeRequest handleCountChangeRequest){
        Long blogId = handleCountChangeRequest.getBlogId();
        String type = handleCountChangeRequest.getType();
        if(blogId == null || type == null){
            return;
        }
        switch (type){
            case "Liked":
                // 1. 处理点赞
                blogService.handelLikedCountChange(blogId);
                break;
            case "View":
                // 2. 处理浏览
                blogService.handelViewCountChange(blogId);
                break;
            case "Collect":
                // 3. 处理收藏
                blogService.handelCollectCountChange(blogId);
                break;
            default:
        }
    }


    /**
     * 获取 publish | liked | collect
     * @param userId userId
     * @param type 类型 Liked | View | Collect
     * @return
     */
    @GetMapping("/getBlogsByType")
    @Parameters({
            @Parameter(name = "token",description = "请求token",required = true,in = ParameterIn.HEADER),
    })
    public Result getBlogsByType(Long userId, String type) {
        if(type == null || userId == null){
            return Result.fail("参数不能为空！");
        }
        switch (type) {
            case "Publish":
                // 1. 处理点赞
                return blogService.getPublishBlogsByUserId(userId);
            case "Collect":
                // 2. 处理浏览
                return blogService.getCollectBlogsByUserId(userId);
            case "Liked":
                // 3. 处理收藏
                return blogService.getLikedBlogsByUserId(userId);
            default:

        }
        return Result.fail("出错啦，输入的type不存在！");
    }


}


